﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace FC.Utils
{
    public static class Converter
    {
        /// <summary>
        /// 自动类型转换，可以将该类的对象按照属性的对应关系自动转换为其他类的对象
        /// </summary>
        /// <typeparam name="T">该类类型</typeparam>
        /// <typeparam name="H">目标类类型</typeparam>
        /// <param name="o">该类的对象</param>
        /// <param name="that">目标类对象</param>
        /// <returns>目标类对象</returns>
        public static H Convert<T,H>(this T o, H that) where T : class where H : class
        {
            //获取 T 的类型
            Type typeT = typeof(T);
            //获取 H 的类型
            Type typeH = typeof(H);
            
            //获取 T 类型的所有公共属性
            List<PropertyInfo> propertiesT = new List<PropertyInfo>(typeT.GetProperties());
            //获取 T 类型的所有公共属性
            List<PropertyInfo> propertiesH = new List<PropertyInfo>(typeH.GetProperties());
            
            foreach (var pT in propertiesT)
            {
                PropertyInfo pH = null;
                if(pT.Name == "Id")
                {
                    string temp = typeT.Name + "Id";
                    pH = propertiesH.Find(x => x.Name == typeT.Name + "Id" && x.PropertyType == pT.PropertyType);
                }
                else
                {
                    //在 H 类型中 查找与 T 类型对应的属性
                    pH = propertiesH.Find(x => x.Name == pT.Name && x.PropertyType == pT.PropertyType);
                }
                if (pH != null)
                {
                    pH.SetValue(that, pT.GetValue(o), null);
                }
            }
            
            return that;
        }

        /// <summary>
        /// 将一个 32位 十进制整型数字转化为二进制字符串
        /// </summary>
        /// <param name="number">32位 十进制整型数字</param>
        /// <returns>二进制字符串</returns>
        public static string ToBinary(this int number)
        {
            string result = "";
            while(number > 0)
            {
                result = (number & 1).ToString() + result;
                number >>= 1;
            }
            return result;
        }

        /// <summary>
        /// 将一个 32位 十进制整型数字转化为八进制字符串
        /// </summary>
        /// <param name="number">32位 十进制整型数字</param>
        /// <returns>八进制字符串</returns>
        public static string ToOctal(this int number, bool AddTag = true)
        {
            string result = "";
            while (number > 0)
            {
                result = (number & 7).ToString() + result;
                number >>= 3;
            }
            return AddTag ? "0" + result : result;
        }

        /// <summary>
        /// 将一个 32位 十进制整型数字转化为十六进制字符串
        /// </summary>
        /// <param name="number">32位 十进制整型数字</param>
        /// <returns>十六进制字符串</returns>
        public static string ToHex(this int number, bool AddTag = true)
        {
            string result = "";
            while (number > 0)
            {
                int n = number & 15;
                result = (n < 10 ? n.ToString() : ((char)(n - 10 + 'A')).ToString()) + result;
                number >>= 4;
            }
            return AddTag ? "0x" + result : result;
        }

        /// <summary>
        /// 将字符串转化为 32位整型数字，转换失败返回 0
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>32位整型数字</returns>
        public static int ToInt32(this string str)
        {
            int result = 0;
            bool success = int.TryParse(str, out result);
            return result;
        }

        /// <summary>
        /// 将字符串转化为 64位整型数字，转换失败返回 0
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>64位整型数字</returns>
        public static long ToInt64(this string str)
        {
            long result = 0;
            bool success = long.TryParse(str, out result);
            return result;
        }
    }
}
